/* Soubor je ulozen v kodovani UTF-8.
 * Kontrola kódování: Příliš žluťoučký kůň úpěl ďábelské ódy. */
package cz.pecinovsky.english.pojj.adv_demo.cesta_školou.hra;

import cz.pecinovsky.english.pojj.adv_framework.game_gui.IGameG;

import cz.pecinovsky.english.pojj.adv_framework.game_txt.IGame;

import cz.pecinovsky.english.pojj.adv_framework.scenario.TypeOfScenario;
import cz.pecinovsky.english.pojj.adv_framework.scenario.ScenarioStep;
import cz.pecinovsky.english.pojj.adv_framework.scenario.AScenarioManager;

import cz.pecinovsky.english.pojj.adv_framework.test_util._Test_101;
import cz.pecinovsky.english.pojj.adv_framework.test_util._Test_115;


import static cz.pecinovsky.english.pojj.adv_framework.scenario.TypeOfStep.*;

/*
import static cz.pecinovsky.česky.pojj.adventura.cesta_školou.SS_CestaSkolou.*;
*/

/*******************************************************************************
 * Instance třída {@code SS_CestaSkolou} slouží jako správce scénářů,
 * které mají prověřit a/nebo demonstrovat správnou funkci plánované hry.
 * Jednotlive scénáře jsou iterovatelné posloupností kroků specifikovaných
 * instancemi třídy <code>ScenarioStep</code> z rámce, do nějž se hra začleňuje.
 * <p>
 * Správce scénářů je jedináček, který má na starosti všechny scénáře
 * týkající se s ním sdružené hry.
 *
 * @author Rudolf PECINOVSKÝ
 * @version 3.00,  22.11.2006
 */
public class SS_CestaSkolou extends AScenarioManager
{
//== KONSTANTNÍ ATRIBUTY TŘÍDY =================================================

    /** Třída, jejíž instance jsou zde spravovány. */
    private final static Class<? extends IGame> TŘÍDA = null;

    /** Jmeno autora dane tridy. */
    private static final String autor = "PECINOVSKÝ Rudolf";

    /** X-name autora/autorky třídy. */
    private static final String xname = "XPECR999";


    /***************************************************************************
     * Konstruktor plnohodnotné instance třídy {@link ScenarioStep}
     * vyžaduje následující parametry:
     *      String   příkaz;    //Příkaz realizující tetno krok scénáře
     *      String   zpráva;    //Zpráva vypsaná po zadání příkazu
     *      String   prostor;   //Prostor, v něž skončí hráč po zadání příkazu
     *      String[] východy;   //Aktuální východy z aktuálního prostoru
     *      String[] objekty;   //Objekty vyskytující se v daném prostoru
     *      String[] batoh;     //Aktuální obsah batohu
     *      TypeOfStep typTestu;  //Typ daného kroku testu
     */

    public static final String //Příkazy
        pJDI    = "Jdi",
        pPOLOŽ  = "Polož",
        pZVEDNI = "Zvedni",
        pKONEC  = "Konec",
        pNÁPOVĚDA="?",
        p       = "PREFIX PŘÍKAZU"
        ;

    public static final String //Místnosti
        mHALA     = "Hala",
        mUČEBNA   = "Ucebna",
        mBUFET    = "Bufet",
        mCHODBA   = "Chodba",
        mKANCELÁŘ = "Kancelar",
        m         = "PREFIX MÍSTNOSTÍ"
        ;

    public static final String //Popisy (description) místností
        dHALA     = "vstupni hala budovy VSE na Jiznim meste",
        dUČEBNA   = "prednaskova ucebna 103JM",
        dBUFET    = "bufet, kam si muzete zajit na svacinku",
        dCHODBA   = "spojovaci chodba",
        dKANCELÁŘ = "kancelar vaseho vyucujiciho Javy",
        d         = "PREFIX POPISŮ MÍSTNOSTÍ"
        ;

    public static final String //Předměty
        oPENÍZE   = "Peníze",
        oKOLA     = "Kola",
        oPULT     = "Pult",
        oPROSPEKT = "Prospekt",
        o         = "PREFIX OBJEKTŮ"
        ;

    public static final String //Texty
        zUVÍTÁNÍ  = "Vitejte!\n" +
                    "Toto je nova, neuveritelne nudna adventura.\n" +
                    "Nebudete-li si vědět rady, zadejte otazník (?).\n",
        zJDI      = "Jste v mistnosti/prostoru ",
        zZVEDNUTÍ = "Zvednul(a) jste předmět: ",
        zPOLOŽENÍ = "Položil(a) jste předmět: ",
        zKONEC    = "Hra ukončena příkazem konec.",
        zNIC             = "Omylem zaqdaný prázdný příkaz",
        zNEZNÁM_AKCI     = "Nevím, co tím myslíš. Zadaný příkaz neznám.",
        zNENÍ_SOUSED     = "Odtud není možno přejít do místnosti: ",
        zNENÍ_PŘEDMĚT    = "Zadaný předmět v místnosti není: ",
        zTEŽKÝ_PŘEDMĚT   = "Zadaný předmět nejde zvednout: ",
        zPLNÝ_BATOH      = "Máš obě ruce plné, předmět nejde zvednout: ",
        zNEMÁM_PŘEDMĚT   = "Zadaný předmět nemáš v ruce: ",
        zNÁPOVĚDA        = "Ztratil ses. Jsi sam(a). Toulas se\n"
                            + "po arealu skoly na Jiznim meste.\n"
                            + "\n"
                            + "Muzes zadat tyto prikazy:\n",

        zPŘEDMĚT_NEZADAN = "Je třeba zadat předmět, s nímž se má manipulovat",
        z         = "PREFIX ZPRÁV"
        ;

    public static final String //Pomocné konstanty
        M = " ";    //Mezera


    static { ScenarioStep.setIndex(1); }
    private static final ScenarioStep ksSTART =
        new ScenarioStep( "", //Název prvního příkazu musí být prázdný řetězec
            zUVÍTÁNÍ,
            mHALA,
            new String[] { mUČEBNA, mCHODBA, mBUFET }, //Sousedé
            new String[] {  },  //Objekty
            new String[] { oPENÍZE },  //Batoh
            tsSTART );

    /***************************************************************************
     * Základní scénář popisující možný úspěšný průběh hry.
     */
    private static final ScenarioStep[] základní =
    {
        ksSTART,

        new ScenarioStep( pJDI +M+ mBUFET, //Příkaz
            zJDI + dBUFET,  //Zpráva
            mBUFET,  //Místnost
            new String[] { mHALA }, //Sousedé
            new String[] { oPULT, oKOLA, oKOLA, oKOLA, oPROSPEKT, oPROSPEKT },  //Objekty
            new String[] { oPENÍZE },  //Batoh
            tsMOVE ),

        new ScenarioStep( pPOLOŽ +M+ oPENÍZE, //Příkaz
            zPOLOŽENÍ + oPENÍZE,  //Zpráva
            mBUFET,  //Místnost
            new String[] { mHALA }, //Sousedé
            new String[] { oPULT, oKOLA, oKOLA, oKOLA, oPROSPEKT, oPROSPEKT, oPENÍZE },  //Objekty
            new String[] { },  //Batoh
            tsPUT_DOWN ),

        new ScenarioStep( pZVEDNI +M+ oKOLA, //Příkaz
            zZVEDNUTÍ + oKOLA,  //Zpráva
            mBUFET,  //Místnost
            new String[] { mHALA }, //Sousedé
            new String[] { oPULT, oKOLA, oKOLA, oPROSPEKT, oPROSPEKT, oPENÍZE },  //Objekty
            new String[] { oKOLA },  //Batoh
            tsPICK_UP ),

        new ScenarioStep( pJDI +M+ mHALA, //Příkaz
            zJDI + dHALA,  //Zpráva
            mHALA,  //Místnost
            new String[] { mUČEBNA, mCHODBA, mBUFET }, //Sousedé
            new String[] {  },  //Objekty
            new String[] { oKOLA },  //Batoh
            tsMOVE ),

        new ScenarioStep( pJDI +M+ mUČEBNA, //Příkaz
            zJDI + dUČEBNA,  //Zpráva
            mUČEBNA,  //Místnost
            new String[] { mHALA }, //Sousedé
            new String[] {  },  //Objekty
            new String[] { oKOLA },  //Batoh
            tsMOVE ),

        new ScenarioStep( pKONEC,
            zKONEC,
            mUČEBNA,  //Místnost
            new String[] { mHALA }, //Sousedé
            new String[] {  },  //Objekty
            new String[] { oKOLA },  //Batoh
            tsEND )
        //V úspěsném scénáři nemusí být typ posledního příkazu tsEND
        //Hra může končit i prostým dosažením požadovaného cíle
    };

    static { ScenarioStep.setIndex(2); }

    /***************************************************************************
     * Základní chybový scénář definující reakce
     * na povinnou sadu chybových stavů.
     */
    private static final ScenarioStep[] chybový =
    {
        ksSTART,

        new ScenarioStep( "",
            zNIC,
            mHALA,
            new String[] { mUČEBNA, mCHODBA, mBUFET }, //Sousedé
            new String[] {  },  //Objekty
            new String[] { oPENÍZE },  //Batoh
            tsEMPTY ),

        new ScenarioStep( "mBUFET",
            zNEZNÁM_AKCI,
            mHALA,
            new String[] { mUČEBNA, mCHODBA, mBUFET }, //Sousedé
            new String[] {  },  //Objekty
            new String[] { oPENÍZE },  //Batoh
            tsUNKNOWN ),

        new ScenarioStep( pJDI +M+ mHALA,
            zNENÍ_SOUSED + mHALA,
            mHALA,
            new String[] { mUČEBNA, mCHODBA, mBUFET }, //Sousedé
            new String[] {  },  //Objekty
            new String[] { oPENÍZE },  //Batoh
            tsBAD_NEIGHBOR ),

        new ScenarioStep( pJDI +M+ mBUFET, //Příkaz
            zJDI + dBUFET,  //Zpráva
            mBUFET,  //Místnost
            new String[] { mHALA }, //Sousedé
            new String[] { oPULT, oKOLA, oKOLA, oPROSPEKT, oPROSPEKT, oKOLA },  //Objekty
            new String[] { oPENÍZE },  //Batoh
            tsMOVE ),

        new ScenarioStep( pZVEDNI +M+ oPENÍZE,
            zNENÍ_PŘEDMĚT + oPENÍZE,
            mBUFET,  //Místnost
            new String[] { mHALA }, //Sousedé
            new String[] { oPULT, oPROSPEKT, oPROSPEKT, oKOLA, oKOLA, oKOLA },  //Objekty
            new String[] { oPENÍZE },  //Batoh
            tsBAD_OBJECT ),

        new ScenarioStep( pZVEDNI +M+ oPULT,
            zTEŽKÝ_PŘEDMĚT + oPULT,
            mBUFET,  //Místnost
            new String[] { mHALA }, //Sousedé
            new String[] { oPULT, oPROSPEKT, oPROSPEKT, oKOLA, oKOLA, oKOLA },  //Objekty
            new String[] { oPENÍZE },  //Batoh
            tsUNMOVABLE ),

        new ScenarioStep( pZVEDNI +M+ oPROSPEKT,
            zZVEDNUTÍ + oPROSPEKT,
            mBUFET,  //Místnost
            new String[] { mHALA }, //Sousedé
            new String[] { oPULT, oPROSPEKT, oKOLA, oKOLA, oKOLA },  //Objekty
            new String[] { oPENÍZE, oPROSPEKT },  //Batoh
            tsPICK_UP ),

        new ScenarioStep( pZVEDNI +M+ oPROSPEKT,
            zPLNÝ_BATOH + oPROSPEKT,
            mBUFET,  //Místnost
            new String[] { mHALA }, //Sousedé
            new String[] { oPULT, oPROSPEKT, oKOLA, oKOLA, oKOLA },  //Objekty
            new String[] { oPENÍZE, oPROSPEKT },  //Batoh
            tsBAG_FULL ),

        new ScenarioStep( pPOLOŽ +M+ oKOLA,
            zNEMÁM_PŘEDMĚT + oKOLA,
            mBUFET,  //Místnost
            new String[] { mHALA }, //Sousedé
            new String[] { oPULT, oPROSPEKT, oKOLA, oKOLA, oKOLA },  //Objekty
            new String[] { oPENÍZE, oPROSPEKT },  //Batoh
            tsNOT_IN_BAG ),

        new ScenarioStep( pNÁPOVĚDA,
            zNÁPOVĚDA,
            mBUFET,  //Místnost
            new String[] { mHALA }, //Sousedé
            new String[] { oPULT, oPROSPEKT, oKOLA, oKOLA, oKOLA },  //Objekty
            new String[] { oPENÍZE, oPROSPEKT },  //Batoh
            tsHELP ),

        new ScenarioStep( pKONEC,
            zKONEC,
            mBUFET,  //Místnost
            new String[] { mHALA }, //Sousedé
            new String[] { oPULT, oPROSPEKT, oKOLA, oKOLA, oKOLA },  //Objekty
            new String[] { oPENÍZE, oPROSPEKT },  //Batoh
            tsEND )
    };


    /** Jediná instance této třídy. Spravuje všechny scénáře sdružené hry. */
    private static final SS_CestaSkolou SS = new SS_CestaSkolou();



//== PROMĚNNÉ ATRIBUTY TŘÍDY ===================================================
//== STATICKÝ INICIALIZAČNÍ BLOK - STATICKÝ KONSTRUKTOR ========================
//== KONSTANTNÍ ATRIBUTY INSTANCÍ ==============================================
//== PROMĚNNÉ ATRIBUTY INSTANCÍ ================================================
//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ TŘÍDY ========================================
//== OSTATNÍ NESOUKROMÉ METODY TŘÍDY ===========================================

//##############################################################################
//== KONSTRUKTORY A TOVÁRNÍ METODY =============================================

    /***************************************************************************
     * Vrátí správce scénářů - jedinou instanci této třídy.
     *
     * @return Správce scénářů
     */
    public static SS_CestaSkolou getInstance()
    {
        return SS;
    }


    /***************************************************************************
     * Vytvoří instanci představující správce scénářů hry.
     */
    private SS_CestaSkolou()
    {
        super(autor, xname, TŘÍDA);

        addScenario("Základní", TypeOfScenario.scHAPPY, základní);
        addScenario("Chybový",  TypeOfScenario.scMISTAKES, chybový);
        seal();
    }



//== ABSTRAKTNÍ METODY =========================================================
//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ INSTANCÍ =====================================
//== OSTATNÍ NESOUKROMÉ METODY INSTANCÍ ========================================
//== SOUKROMÉ A POMOCNÉ METODY TŘÍDY ===========================================
//== SOUKROMÉ A POMOCNÉ METODY INSTANCÍ ========================================
//== INTERNÍ DATOVÉ TYPY =======================================================
//== TESTOVACÍ METODY A TŘÍDY ==================================================

    /***************************************************************************
     * Základní test ověřující, jestli správce scénářů vyhovuje
     * zadným okrajovým podmínkám.
     */
    public static void testSprávceScénářů()
    {
        _Test_101 test = _Test_101.getInstance(SS);
        test.testScenarioManager();
    }


    /***************************************************************************
     * Testování funkce hry prováděné postupně
     * prostřednictvím všech scénářů daného správce
     */
    public static void prověrkaHry()
    {
        IGame     hra  = SS.getGame();
        _Test_101 test = _Test_101.getInstance(hra);
        test.testGame();
    }


    /***************************************************************************
     * Test ověřujícífunkci textové verze hry.
     */
    public static void testTXT()
    {
        IGame     hra  = SS.getGame();
        _Test_101 test = _Test_101.getInstance(hra);
        test.playGameByScenario(INDEX_GUI_TEST);
    }


    /***************************************************************************
     * Test demonstrující hraní hry na daném GUI.
     */
    public static void testGUI()
    {
        IGameG    hra  = (IGameG)SS.getGame();
        _Test_115 test = _Test_115.getInstance(hra);
        test.playGameByScenario(INDEX_GUI_TEST);
    }


    /** @param args Parametry příkazového řádku - nepoužívané. */
    public static void main( String[] args )
    {
        testTXT();
    }
}
